#include "OgreSK.h"

template<> OgreSK *Ogre::Singleton<OgreSK>::msSingleton = 0;

OgreSK::OgreSK(void)
{
	m_pRoot = 0;
	m_pRenderWnd = 0;
	m_pLog = 0;
	m_pViewport = 0;

	m_pInputMgr = 0;
	m_pKeyboard = 0;
	m_pMouse = 0;

	m_pTrayMgr = 0;

	m_sPluginsCfg = Ogre::StringUtil::BLANK;
	m_sResourcesCfg = Ogre::StringUtil::BLANK;
}


OgreSK::~OgreSK(void)
{
	OgreSK::getSingletonPtr()->m_pLog->logMessage("Shutdown Ogre...");
	if(m_pInputMgr) OIS::InputManager::destroyInputSystem(m_pInputMgr);
	if(m_pTrayMgr) delete m_pTrayMgr;
	if(m_pRoot) delete m_pRoot;
}

CEGUI::MouseButton convertButton(OIS::MouseButtonID id)
{
	switch(id)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
	case OIS::MB_Right:
		return CEGUI::RightButton;
	case OIS::MB_Middle:
		return CEGUI::MiddleButton;
	default:
		return CEGUI::LeftButton;
	}
}

bool OgreSK::initialiseOgre(void)
{
	Ogre::LogManager* tempLog = new Ogre::LogManager();

	m_pLog = Ogre::LogManager::getSingletonPtr()->createLog("OSAirportOgre.log", true, true, false);
	m_pLog->setDebugOutputEnabled(true);

#ifdef _DEBUG
	m_sPluginsCfg = "plugins_d.cfg";
	m_sResourcesCfg = "resources_d.cfg";
#else
	m_sPluginsCfg = "plugins.cfg";
	m_sResourcesCfg = "resources.cfg";
#endif

	m_pRoot = new Ogre::Root(m_sPluginsCfg);

	if(!m_pRoot->showConfigDialog())
		return false;

	m_pRenderWnd = m_pRoot->initialise(true, "testApp");

	m_pViewport = m_pRenderWnd->addViewport(0);
	m_pViewport->setBackgroundColour(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
	m_pViewport->setCamera(0);

	size_t hWnd = 0;
	m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd);

	OIS::ParamList parameters;
	parameters.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd)));

	m_pInputMgr = OIS::InputManager::createInputSystem(parameters);

	m_pKeyboard = static_cast<OIS::Keyboard*>(m_pInputMgr->createInputObject(OIS::OISKeyboard, true));
	m_pMouse = static_cast<OIS::Mouse*>(m_pInputMgr->createInputObject(OIS::OISMouse, true));

	m_pMouse->getMouseState().height = m_pRenderWnd->getHeight();
	m_pMouse->getMouseState().width = m_pRenderWnd->getWidth();

	m_pKeyboard->setEventCallback(this);
	m_pMouse->setEventCallback(this);

	loadResources();

	initialiseCEGUI();

	m_pTimer = new Ogre::Timer();
	m_pTimer->reset();

	m_pTrayMgr = new OgreBites::SdkTrayManager("DebugTrayManager", m_pRenderWnd, m_pMouse, 0);
	return true;
}

bool OgreSK::initialiseCEGUI(void)
{
	m_pCEGUIRenderer = &CEGUI::OgreRenderer::bootstrapSystem();

	CEGUI::Imageset::setDefaultResourceGroup("Imagesets");
	CEGUI::Font::setDefaultResourceGroup("Fonts");
	CEGUI::Scheme::setDefaultResourceGroup("Schemes");
	CEGUI::WidgetLookManager::setDefaultResourceGroup("LookNFeel");
	CEGUI::WindowManager::setDefaultResourceGroup("Layouts");

	CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
	CEGUI::System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");

	return true;
}

bool OgreSK::loadResources(void)
{
	Ogre::ConfigFile cf;
	cf.load(m_sResourcesCfg);

	Ogre::ConfigFile::SectionIterator secIter = cf.getSectionIterator();

	Ogre::String secName, typeName, archName;
	while(secIter.hasMoreElements())
	{
		secName = secIter.peekNextKey();
		Ogre::ConfigFile::SettingsMultiMap *settings = secIter.getNext();
		Ogre::ConfigFile::SettingsMultiMap::iterator i;
		for(i = settings->begin(); i != settings->end(); i++)
		{
			typeName = i->first;
			archName = i->second;
			
			Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
		}
	}

	Ogre::ResourceGroupManager::getSingletonPtr()->initialiseAllResourceGroups();

	return true;
}

void OgreSK::updateOgre(double timeSinceLastFrame)
{
}

bool OgreSK::keyPressed(const OIS::KeyEvent &evt)
{
	CEGUI::System &sys = CEGUI::System::getSingleton();
	sys.injectKeyDown(evt.key);
	sys.injectChar(evt.text);

	return true;
}

bool OgreSK::keyReleased(const OIS::KeyEvent &evt)
{
	CEGUI::System::getSingleton().injectKeyUp(evt.key);

	return true;
}

bool OgreSK::mouseMoved(const OIS::MouseEvent &evt)
{
	return true;
}

bool OgreSK::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));

	return true;
}

bool OgreSK::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));

	return true;
}